/*
 * Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
 *
 * Licensed under the Mulan PSL v2.
 * You can use this file according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of the License at
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
 * FOR MORE DETAILS.
 */

#pragma once

#include <iostream>
#include <cassert>

#include "DataStructure/Common/Id.h"
#include "DataStructure/Common/Out.h"
#include "DataStructure/Common/Real.h"
#include "DataStructure/Input/Solver/AnaysisTypes.h"

#include "DBManager/Common/DBManagerNamespace.h"
SG_DBMANAGER_NAMESPACE_OPEN
class ResultDomainsService; 
SG_DBMANAGER_NAMESPACE_CLOSE

SG_DBMANAGER_POST_NAMESPACE_OPEN
/**
 * @brief    数据的域
 * 根据不同的分析类型、工况号、阶、步分为不同的域
 * @author   wxc
 * @date     2024.12.12
 */
class DomainRequest
{
    using Real    = SG::DataStructure::Common::Real;
    using I64     = SG::DataStructure::Common::I64;
    using Id      = SG::DataStructure::Common::Id;
    using IdArray = SG::DataStructure::Common::IdArray;
    using SOLType = SG::DataStructure::FEM::SOLType;
    
public:
    /// @brief DOMAINS中RANDOM
    enum class RandomResultType : I64
    {
        UNKNOWN = 0,  // 位置
        PSD     = 1,  // 位移的PSD的自功率谱
        PSDS    = 2,  // 位移的PSD的互功率谱
        AVG     = 3,  // 位移的均方根值（最后1个频率点）
        ZERO    = 4,  // 过零次数
        AVGSUM  = 5,  // 位移的累积均方根值
    };

    DomainRequest () = delete;

    explicit DomainRequest (Id subcaseId) : subcaseId (subcaseId)
    {}

    DomainRequest (SOLType type, Id subcaseId) : subcaseId (subcaseId), analysisType (type)
    {}

    DomainRequest (Id subcaseId, Real time_mode_step) : subcaseId (subcaseId), time_mode_step (time_mode_step)
    {}

    DomainRequest (SOLType type, Id subcaseId, Real time_mode_step)
        : subcaseId (subcaseId), time_mode_step (time_mode_step), analysisType (type)
    {}

    DomainRequest (SOLType type, Id subcaseId, Real time_mode_step, Real eigi)
        : subcaseId (subcaseId), time_mode_step (time_mode_step), eigi (eigi), analysisType (type)
    {}

    DomainRequest (Id subcaseId, Real time_mode_step, RandomResultType random)
        : subcaseId (subcaseId), time_mode_step (time_mode_step), random (random)
    {
        assert (random != RandomResultType::UNKNOWN);
        switch (random)
        {
        case RandomResultType::PSD:
        case RandomResultType::PSDS:
        case RandomResultType::AVGSUM:
            analysisType = SOLType::SOL_SEMFREQ;
            break;
        case RandomResultType::AVG:
        case RandomResultType::ZERO:
            analysisType = SOLType::SOL_SESTATIC;
            break;
        default:
            break;
        }
    }

    I64 GetTimeModeStepI64 () const
    {
        return static_cast<I64> (time_mode_step);
    }

    Real GetTimeModeStepReal () const
    {
        return time_mode_step;
    }

  private:
    Id               subcaseId      = -1;                         // subcaseId
    Real             time_mode_step = -1.0;                       // time or mode or step
    Real             eigi           = -1.0;                       // eigi
    SOLType          analysisType   = SOLType::SOL_UNKNOWN;       // 求解类型
    RandomResultType random         = RandomResultType::UNKNOWN;  // random

    friend class SG::DBManager::ResultDomainsService;
};
SG_DBMANAGER_POST_NAMESPACE_CLOSE